home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet multimedia / Muzyka / Edytory sampli (probek dzwieku) / ZynAddSubFX_2.2.0 / Setup_ZynAddSubFX-2.2.0.exe / source code / Misc / XMLwrapper.C < prev    next >
C/C++ Source or Header  |  2005-03-14  |  13KB  |  532 lines

  1. /*
  2.   ZynAddSubFX - a software synthesizer
  3.  
  4.   XMLwrapper.C - XML wrapper
  5.   Copyright (C) 2003-2005 Nasca Octavian Paul
  6.   Author: Nasca Octavian Paul
  7.  
  8.   This program is free software; you can redistribute it and/or modify
  9.   it under the terms of version 2 of the GNU General Public License 
  10.   as published by the Free Software Foundation.
  11.  
  12.   This program is distributed in the hope that it will be useful,
  13.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.   GNU General Public License (version 2) for more details.
  16.  
  17.   You should have received a copy of the GNU General Public License (version 2)
  18.   along with this program; if not, write to the Free Software Foundation,
  19.   Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  20.  
  21. */
  22.  
  23. #include "XMLwrapper.h"
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <zlib.h>
  27.  
  28. #include "../globals.h"
  29. #include "Util.h"
  30.  
  31. int xml_k=0;
  32. char tabs[STACKSIZE+2];
  33.  
  34. const char *XMLwrapper_whitespace_callback(mxml_node_t *node,int where){
  35.     const char *name=node->value.element.name;
  36.  
  37.     if ((where==MXML_WS_BEFORE_OPEN)&&(!strcmp(name,"?xml"))) return(NULL);
  38.     if ((where==MXML_WS_BEFORE_CLOSE)&&(!strcmp(name,"string"))) return(NULL);
  39.  
  40.     if ((where==MXML_WS_BEFORE_OPEN)||(where==MXML_WS_BEFORE_CLOSE)) {
  41. /*    const char *tmp=node->value.element.name;
  42.     if (tmp!=NULL) {
  43.         if ((strstr(tmp,"par")!=tmp)&&(strstr(tmp,"string")!=tmp)) {
  44.         printf("%s ",tmp);
  45.         if (where==MXML_WS_BEFORE_OPEN) xml_k++;
  46.         if (where==MXML_WS_BEFORE_CLOSE) xml_k--;
  47.         if (xml_k>=STACKSIZE) xml_k=STACKSIZE-1;
  48.         if (xml_k<0) xml_k=0;
  49.         printf("%d\n",xml_k);
  50.         printf("\n");
  51.         };
  52.         
  53.     };
  54.     int i=0;
  55.     for (i=1;i<xml_k;i++) tabs[i]='\t';
  56.     tabs[0]='\n';tabs[i+1]='\0';
  57.     if (where==MXML_WS_BEFORE_OPEN) return(tabs);
  58.         else return("\n");
  59. */    
  60.     return("\n");
  61.     };
  62.     
  63.     return(0);
  64. };
  65.  
  66.  
  67. XMLwrapper::XMLwrapper(){
  68.     ZERO(&parentstack,(int)sizeof(parentstack));
  69.     ZERO(&values,(int)sizeof(values));
  70.  
  71.     minimal=true;
  72.     stackpos=0;
  73.  
  74.     information.PADsynth_used=false;
  75.     
  76.     tree=mxmlNewElement(MXML_NO_PARENT,"?xml");
  77.     mxmlElementSetAttr(tree,"version","1.0");
  78.     mxmlElementSetAttr(tree,"encoding","UTF-8");
  79.  
  80.     
  81.     mxml_node_t *doctype=mxmlNewElement(tree,"!DOCTYPE");
  82.     mxmlElementSetAttr(doctype,"ZynAddSubFX-data",NULL);
  83.  
  84.     node=root=mxmlNewElement(tree,"ZynAddSubFX-data");
  85.         
  86.     mxmlElementSetAttr(root,"version-major","1");
  87.     mxmlElementSetAttr(root,"version-minor","1");
  88.     mxmlElementSetAttr(root,"ZynAddSubFX-author","Nasca Octavian Paul");
  89.  
  90.     //make the empty branch that will contain the information parameters
  91.     info=addparams0("INFORMATION");
  92.     
  93.     //save zynaddsubfx specifications
  94.     beginbranch("BASE_PARAMETERS");
  95.     addpar("max_midi_parts",NUM_MIDI_PARTS);
  96.     addpar("max_kit_items_per_instrument",NUM_KIT_ITEMS);
  97.  
  98.     addpar("max_system_effects",NUM_SYS_EFX);
  99.     addpar("max_insertion_effects",NUM_INS_EFX);
  100.     addpar("max_instrument_effects",NUM_PART_EFX);
  101.  
  102.     addpar("max_addsynth_voices",NUM_VOICES);
  103.     endbranch();
  104.  
  105. };
  106.  
  107. XMLwrapper::~XMLwrapper(){
  108.     if (tree!=NULL) mxmlDelete(tree);
  109. };
  110.  
  111. bool XMLwrapper::checkfileinformation(char *filename){
  112.     stackpos=0;
  113.     ZERO(&parentstack,(int)sizeof(parentstack));
  114.     information.PADsynth_used=false;
  115.  
  116.     if (tree!=NULL) mxmlDelete(tree);tree=NULL;
  117.     char *xmldata=doloadfile(filename);
  118.     if (xmldata==NULL) return(-1);//the file could not be loaded or uncompressed
  119.  
  120.  
  121.     char *start=strstr(xmldata,"<INFORMATION>");
  122.     char *end=strstr(xmldata,"</INFORMATION>");
  123.  
  124.     if ((start==NULL)||(end==NULL)||(start>end)) {
  125.     delete(xmldata);
  126.     return(false);
  127.     };
  128.     end+=strlen("</INFORMATION>");
  129.     end[0]='\0';    
  130.     
  131.     tree=mxmlNewElement(MXML_NO_PARENT,"?xml");
  132.     node=root=mxmlLoadString(tree,xmldata,MXML_OPAQUE_CALLBACK);
  133.     if (root==NULL) {
  134.     delete(xmldata);
  135.     mxmlDelete(tree);
  136.     node=root=tree=NULL;
  137.     return(false);
  138.     };
  139.  
  140.     root=mxmlFindElement(tree,tree,"INFORMATION",NULL,NULL,MXML_DESCEND);
  141.     push(root);
  142.  
  143.     if (root==NULL){
  144.     delete(xmldata);
  145.     mxmlDelete(tree);
  146.     node=root=tree=NULL;
  147.     return(false);
  148.     };
  149.     
  150.     information.PADsynth_used=getparbool("PADsynth_used",false);
  151.  
  152.     exitbranch();
  153.     if (tree!=NULL) mxmlDelete(tree);
  154.     delete(xmldata);
  155.     node=root=tree=NULL;
  156.  
  157.     return(true);
  158. };
  159.  
  160.  
  161. /* SAVE XML members */
  162.  
  163. int XMLwrapper::saveXMLfile(char *filename){
  164.     char *xmldata=getXMLdata();
  165.     if (xmldata==NULL) return(-2);
  166.  
  167.     int compression=config.cfg.GzipCompression;
  168.     
  169.     int fnsize=strlen(filename)+100;
  170.     char *filenamenew=new char [fnsize];
  171.     snprintf(filenamenew,fnsize,"%s",filename);
  172.     
  173.     int result=dosavefile(filenamenew,compression,xmldata);
  174.     
  175.     delete(filenamenew);
  176.     delete(xmldata);    
  177.     return(result);
  178. };
  179.  
  180. char *XMLwrapper::getXMLdata(){
  181.     xml_k=0;
  182.     ZERO(tabs,STACKSIZE+2);
  183.     
  184.     mxml_node_t *oldnode=node;
  185.     
  186.     node=info;
  187.     //Info storing
  188.     addparbool("PADsynth_used",information.PADsynth_used);
  189.     
  190.     node=oldnode;
  191.     char *xmldata=mxmlSaveAllocString(tree,XMLwrapper_whitespace_callback);
  192.  
  193.     return(xmldata);
  194. };
  195.  
  196.  
  197. int XMLwrapper::dosavefile(char *filename,int compression,char *xmldata){
  198.     if (compression==0){
  199.     FILE *file;
  200.     file=fopen(filename,"w");
  201.     if (file==NULL) return(-1);
  202.     fputs(xmldata,file);
  203.     fclose(file);
  204.     } else {
  205.     if (compression>9) compression=9;
  206.     if (compression<1) compression=1;
  207.     char options[10];
  208.     snprintf(options,10,"wb%d",compression);
  209.  
  210.     gzFile gzfile;
  211.     gzfile=gzopen(filename,options);
  212.     if (gzfile==NULL) return(-1);
  213.     gzputs(gzfile,xmldata);
  214.     gzclose(gzfile);
  215.     };
  216.     
  217.     return(0);
  218. };
  219.  
  220.  
  221.  
  222. void XMLwrapper::addpar(char *name,int val){
  223.     addparams2("par","name",name,"value",int2str(val));
  224. };
  225.  
  226. void XMLwrapper::addparreal(char *name,REALTYPE val){
  227.     addparams2("par_real","name",name,"value",real2str(val));
  228. };
  229.  
  230. void XMLwrapper::addparbool(char *name,int val){
  231.     if (val!=0) addparams2("par_bool","name",name,"value","yes");
  232.     else addparams2("par_bool","name",name,"value","no");
  233. };
  234.  
  235. void XMLwrapper::addparstr(char *name,char *val){
  236.     mxml_node_t *element=mxmlNewElement(node,"string");
  237.     mxmlElementSetAttr(element,"name",name);
  238.     mxmlNewText(element,0,val);
  239. };
  240.  
  241.  
  242. void XMLwrapper::beginbranch(char *name){
  243.     push(node);
  244.     node=addparams0(name);
  245. };
  246.  
  247. void XMLwrapper::beginbranch(char *name,int id){
  248.     push(node);
  249.     node=addparams1(name,"id",int2str(id));
  250. };
  251.  
  252. void XMLwrapper::endbranch(){
  253.     node=pop();
  254. };
  255.  
  256.  
  257.  
  258. /* LOAD XML members */
  259.  
  260. int XMLwrapper::loadXMLfile(const char *filename){
  261.     if (tree!=NULL) mxmlDelete(tree);
  262.     tree=NULL;
  263.  
  264.     ZERO(&parentstack,(int)sizeof(parentstack));
  265.     ZERO(&values,(int)sizeof(values));
  266.  
  267.     stackpos=0;
  268.  
  269.     char *xmldata=doloadfile(filename);    
  270.     if (xmldata==NULL) return(-1);//the file could not be loaded or uncompressed
  271.     
  272.     root=tree=mxmlLoadString(NULL,xmldata,MXML_OPAQUE_CALLBACK);
  273.  
  274.     delete(xmldata);
  275.  
  276.     if (tree==NULL) return(-2);//this is not XML
  277.     
  278.     
  279.     node=root=mxmlFindElement(tree,tree,"ZynAddSubFX-data",NULL,NULL,MXML_DESCEND);
  280.     if (root==NULL) return(-3);//the XML doesnt embbed zynaddsubfx data
  281.     push(root);
  282.  
  283.     values.xml_version.major=str2int(mxmlElementGetAttr(root,"version-major"));
  284.     values.xml_version.minor=str2int(mxmlElementGetAttr(root,"version-minor"));
  285.  
  286.     return(0);
  287. };
  288.  
  289.  
  290. char *XMLwrapper::doloadfile(const char *filename){
  291.     char *xmldata=NULL;
  292.     int filesize=-1;
  293.     
  294.     //try get filesize as gzip data (first)
  295.     gzFile gzfile=gzopen(filename,"rb");
  296.     if (gzfile!=NULL){//this is a gzip file 
  297.     // first check it's size
  298.     while(!gzeof(gzfile)) {
  299.         gzseek (gzfile,1024*1024,SEEK_CUR);
  300.         if (gztell(gzfile)>10000000) {
  301.         gzclose(gzfile);
  302.         goto notgzip;//the file is too big
  303.         };
  304.     };
  305.     filesize=gztell(gzfile);
  306.  
  307.     //rewind the file and load the data
  308.     xmldata=new char[filesize+1];
  309.     ZERO(xmldata,filesize+1);
  310.  
  311.     gzrewind(gzfile);
  312.     gzread(gzfile,xmldata,filesize);
  313.     
  314.     gzclose(gzfile);
  315.     return (xmldata);
  316.     } else {//this is not a gzip file
  317.     notgzip:    
  318.     FILE *file=fopen(filename,"rb");
  319.     if (file==NULL) return(NULL);
  320.     fseek(file,0,SEEK_END);
  321.     filesize=ftell(file);
  322.  
  323.     xmldata=new char [filesize+1];
  324.     ZERO(xmldata,filesize+1);
  325.     
  326.     rewind(file);
  327.     fread(xmldata,filesize,1,file);
  328.     
  329.     fclose(file);
  330.     return(xmldata);
  331.     }; 
  332. };
  333.  
  334. bool XMLwrapper::putXMLdata(char *xmldata){
  335.     if (tree!=NULL) mxmlDelete(tree);
  336.     tree=NULL;
  337.  
  338.     ZERO(&parentstack,(int)sizeof(parentstack));
  339.     ZERO(&values,(int)sizeof(values));
  340.  
  341.     stackpos=0;
  342.  
  343.     if (xmldata==NULL) return (false);
  344.     
  345.     root=tree=mxmlLoadString(NULL,xmldata,MXML_OPAQUE_CALLBACK);
  346.  
  347.     if (tree==NULL) return(false);
  348.     
  349.     node=root=mxmlFindElement(tree,tree,"ZynAddSubFX-data",NULL,NULL,MXML_DESCEND);
  350.     if (root==NULL) return (false);;
  351.     push(root);
  352.  
  353.     return(true);
  354. };
  355.  
  356.  
  357.  
  358. int XMLwrapper::enterbranch(char *name){
  359.     node=mxmlFindElement(peek(),peek(),name,NULL,NULL,MXML_DESCEND_FIRST);
  360.     if (node==NULL) return(0);
  361.  
  362.     push(node);
  363.     return(1);
  364. };
  365.  
  366. int XMLwrapper::enterbranch(char *name,int id){
  367.     snprintf(tmpstr,TMPSTR_SIZE,"%d",id);
  368.     node=mxmlFindElement(peek(),peek(),name,"id",tmpstr,MXML_DESCEND_FIRST);
  369.     if (node==NULL) return(0);
  370.  
  371.     push(node);
  372.     return(1);
  373. };
  374.  
  375.  
  376. void XMLwrapper::exitbranch(){
  377.     pop();
  378. };
  379.  
  380.  
  381. int XMLwrapper::getbranchid(int min, int max){
  382.     int id=str2int(mxmlElementGetAttr(node,"id"));
  383.     if ((min==0)&&(max==0)) return(id);
  384.     
  385.     if (id<min) id=min;
  386.     else if (id>max) id=max;
  387.  
  388.     return(id);
  389. };
  390.  
  391. int XMLwrapper::getpar(char *name,int defaultpar,int min,int max){
  392.     node=mxmlFindElement(peek(),peek(),"par","name",name,MXML_DESCEND_FIRST);
  393.     if (node==NULL) return(defaultpar);
  394.  
  395.     const char *strval=mxmlElementGetAttr(node,"value");
  396.     if (strval==NULL) return(defaultpar);
  397.     
  398.     int val=str2int(strval);
  399.     if (val<min) val=min;
  400.     else if (val>max) val=max;
  401.     
  402.     return(val);
  403. };
  404.  
  405. int XMLwrapper::getpar127(char *name,int defaultpar){
  406.     return(getpar(name,defaultpar,0,127));
  407. };
  408.  
  409. int XMLwrapper::getparbool(char *name,int defaultpar){
  410.     node=mxmlFindElement(peek(),peek(),"par_bool","name",name,MXML_DESCEND_FIRST);
  411.     if (node==NULL) return(defaultpar);
  412.  
  413.     const char *strval=mxmlElementGetAttr(node,"value");
  414.     if (strval==NULL) return(defaultpar);
  415.     
  416.     if ((strval[0]=='Y')||(strval[0]=='y')) return(1);
  417.     else return(0);
  418. };
  419.  
  420. void XMLwrapper::getparstr(char *name,char *par,int maxstrlen){
  421.     ZERO(par,maxstrlen);
  422.     node=mxmlFindElement(peek(),peek(),"string","name",name,MXML_DESCEND_FIRST);
  423.     
  424.     if (node==NULL) return;
  425.     if (node->child==NULL) return;
  426.     if (node->child->type!=MXML_OPAQUE) return;
  427.     
  428.     snprintf(par,maxstrlen,"%s",node->child->value.element.name);
  429.     
  430. };
  431.  
  432. REALTYPE XMLwrapper::getparreal(char *name,REALTYPE defaultpar){
  433.     node=mxmlFindElement(peek(),peek(),"par_real","name",name,MXML_DESCEND_FIRST);
  434.     if (node==NULL) return(defaultpar);
  435.  
  436.     const char *strval=mxmlElementGetAttr(node,"value");
  437.     if (strval==NULL) return(defaultpar);
  438.     
  439.     return(str2real(strval));
  440. };
  441.  
  442. REALTYPE XMLwrapper::getparreal(char *name,REALTYPE defaultpar,REALTYPE min,REALTYPE max){
  443.     REALTYPE result=getparreal(name,defaultpar);
  444.     
  445.     if (result<min) result=min;
  446.     else if (result>max) result=max;
  447.     return(result);
  448. };
  449.  
  450.  
  451. /** Private members **/
  452.  
  453. char *XMLwrapper::int2str(int x){
  454.     snprintf(tmpstr,TMPSTR_SIZE,"%d",x);
  455.     return(tmpstr);
  456. };
  457.  
  458. char *XMLwrapper::real2str(REALTYPE x){
  459.     snprintf(tmpstr,TMPSTR_SIZE,"%g",x);
  460.     return(tmpstr);
  461. };
  462.  
  463. int XMLwrapper::str2int(const char *str){
  464.     if (str==NULL) return(0);
  465.     int result=strtol(str,NULL,10);
  466.     return(result);
  467. };
  468.  
  469. REALTYPE XMLwrapper::str2real(const char *str){
  470.     if (str==NULL) return(0.0);
  471.     REALTYPE result=strtod(str,NULL);
  472.     return(result);
  473. };
  474.  
  475.  
  476. mxml_node_t *XMLwrapper::addparams0(char *name){
  477.     mxml_node_t *element=mxmlNewElement(node,name);
  478.     return(element);
  479. };
  480.  
  481. mxml_node_t *XMLwrapper::addparams1(char *name,char *par1,char *val1){
  482.     mxml_node_t *element=mxmlNewElement(node,name);
  483.     mxmlElementSetAttr(element,par1,val1);
  484.     return(element);
  485. };
  486.  
  487. mxml_node_t *XMLwrapper::addparams2(char *name,char *par1,char *val1,char *par2, char *val2){
  488.     mxml_node_t *element=mxmlNewElement(node,name);
  489.     mxmlElementSetAttr(element,par1,val1);
  490.     mxmlElementSetAttr(element,par2,val2);
  491.     return(element);
  492. };
  493.  
  494.  
  495.  
  496.  
  497. void XMLwrapper::push(mxml_node_t *node){
  498.     if (stackpos>=STACKSIZE-1) {
  499.     printf("BUG!: XMLwrapper::push() - full parentstack\n");
  500.     return;
  501.     };
  502.     stackpos++;
  503.     parentstack[stackpos]=node;
  504.     
  505. //    printf("push %d - %s\n",stackpos,node->value.element.name);
  506.     
  507. };
  508. mxml_node_t *XMLwrapper::pop(){
  509.     if (stackpos<=0) {
  510.     printf("BUG!: XMLwrapper::pop() - empty parentstack\n");
  511.     return (root);
  512.     };
  513.     mxml_node_t *node=parentstack[stackpos];
  514.     parentstack[stackpos]=NULL;
  515.  
  516. //    printf("pop %d - %s\n",stackpos,node->value.element.name);
  517.  
  518.     stackpos--;
  519.     return(node);
  520. };
  521.  
  522. mxml_node_t *XMLwrapper::peek(){
  523.     if (stackpos<=0) {
  524.     printf("BUG!: XMLwrapper::peek() - empty parentstack\n");
  525.     return (root);
  526.     };
  527.     return(parentstack[stackpos]);
  528. };
  529.  
  530.  
  531.  
  532.